import React, { useState, useRef } from "react"; 
import nodeType from "@/components/Node";
import edgeTypes from "@/components/Edge";
import ReactFlow, {
  Controls,
  addEdge,
  Background,
  BackgroundVariant,
  OnLoadParams,
  Elements,
} from "react-flow-renderer";
import { useDispatch, useSelector } from "react-redux";
import { Dispatch, RootState } from "@/store";
import { Modal, Radio, Space, RadioChangeEvent, Input } from "antd";
import style from "./index.module.less";

interface IProps {
  setInstance?: any;
  instance?: any;
  elements?: Elements;
}
const getHash = (len?: number) => {
  let length = len || 8;
  const arr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
  const al = arr.length;
  let chars = "";
  while (length--) {
    chars += arr[Math.floor(Math.random() * al)];
  }
  return chars;
};

const styles = {
   //background: "grey",
  width: "85vw",
  height: "90vh",
};

const Graph = (props: IProps) => {
  const dispatch = useDispatch<Dispatch>();
  const [isModalShow, setIsModalShow] = useState<boolean>(false);
  const [radioValue, setRadioValue] = useState<string>("Association");
  const [inputValue, setInputValue] = useState<string>("文本");
  const [edgeParams, setEdgeParams] = useState<any>({});
  const { reactFlowInstance, elements } = useSelector(
    (state: RootState) => state.diagram
  );
  // 画布的 DOM 容器，用于计算节点坐标
  const graphWrapper = useRef<HTMLDivElement>(null);

  // 画布加载完毕，保存当前画布实例
  const onLoad = (instance: OnLoadParams | null) => {
    setReactFlowInstance(instance);
  };
  const setReactFlowInstance = (instance: OnLoadParams | null) => {
    dispatch.diagram.setFlowInstance(instance);
  };

  const setElements = (els: Elements) => {
    dispatch.diagram.setElements(els);
  };

  // 连线
  const onConnect = (params: any) => {
    setIsModalShow(true);
    setEdgeParams(params);
  };

  const onDrop = (event: any) => {
    event.preventDefault();
    const reactFlowBounds = graphWrapper.current?.getBoundingClientRect() as {
      left?: any;
      top?: any;
    };
    // 获取节点类型
    const type = event.dataTransfer.getData("application/reactflow");
    // 使用 project 将像素坐标转换为内部 ReactFlow 坐标系
    const position = reactFlowInstance.project({
      x: event.clientX - reactFlowBounds?.left,
      y: event.clientY - reactFlowBounds?.top,
    });
    const newNode = {
      id: `id_${getHash(4)}${Date.parse(new Date().toString())}`,
      type,
      position,
      // 传入节点 data
      data: { type: `${type} node` },
    };
    dispatch.diagram.saveFlowNode({
      ...newNode,
    });
    setElements(elements?.concat(newNode) || []);
  };

  const onDragOver = (event: {
    preventDefault: () => void;
    dataTransfer: { dropEffect: string };
  }) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "move";
  };

  // 弹框操作
  const onCancelModal = () => {
    setIsModalShow(false);
    setInputValue(""); // 清空输入框 
  };

  const onRadioChange = (e: RadioChangeEvent) => {
    setRadioValue(e.target.value ?? "");
  };
  const onInputChange = (e: any) => {
    setInputValue(e.target.value ?? "");
  };
  const handleModalOk = () => {
    setElements(
      addEdge(
        { ...edgeParams, data: { text: inputValue }, type: radioValue },
        elements ?? []
      )
    );
    setIsModalShow(false);
  };

  return (
    <div className={style.container} ref={graphWrapper}>
    
      <ReactFlow
        style={styles}
        elements={elements || []}
        onConnect={onConnect}
        nodeTypes={nodeType}
        edgeTypes={edgeTypes}
        onLoad={onLoad}
        onDrop={onDrop}
        onDragOver={onDragOver}
      >
        <Controls />
        <Background variant={BackgroundVariant.Lines} />
      </ReactFlow>
      <Modal
        visible={isModalShow}
        onCancel={onCancelModal}
        onOk={handleModalOk}
      >
       <Radio.Group onChange={onRadioChange} value={radioValue}>
          <Space direction="vertical">
            <Radio value={"Constraint"}>约束</Radio>
            <Radio value={"Contain"}>包含</Radio>
            <Radio value={"Lifeline"}>生命线</Radio>
            <Radio value={"AsynchronousMsg"}>异步消息</Radio>
            <Radio value={"CreateMsg"}>创建消息</Radio>
            <Radio value={"SynchronousMsg"}>同步消息</Radio>
            <Radio value={"ResponseMsg"}>回复消息</Radio>
            <Radio value={"Connect"}>绑定连接器</Radio>
            <Radio value={"Conform"}>符合</Radio>
            <Radio value={"Depend"}>依赖</Radio>
            <Radio value={"Association"}>关联</Radio>
            <Radio value={"Generalization"}>泛化</Radio>
            <Radio value={"Solve"}>满足</Radio>
            <Radio value={"Transfer"}>转移</Radio>

          </Space>
        </Radio.Group>
        <Input value={inputValue} onChange={onInputChange} />
      </Modal>
    </div>
  );
};
export default Graph;